/* 
 * Shuriken is the legal property of its developers. Please refer to the
 * COPYRIGHT file distributed with this
 * source distribution.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

using System;
using System.Collections.Generic;
using System.Text;

namespace Shuriken.Core.UI.StandardUI
{
    /// <summary>
    /// Implements the standard UI 
    /// </summary>
    /// <remarks>
    /// This implements only the subject-action slots. Both of these are present at the same time on the UI
    /// </remarks>
    internal class SUIProvider : Shuriken.Core.UI.IUIProvider 
    {
        private frmMain m_MainForm = null;
        private bool m_TextEntryActive; 

        public SUIProvider()
        {
            m_MainForm = new frmMain();
            m_TextEntryActive = false; 
        }

        #region IUIProvider Members

        /// <summary>
        /// Register the UI Manager with a UI provider
        /// </summary>
        /// <param name="Manager">UI Manager to register</param>
        void IUIProvider.RegisterUIManager(UIManager Manager)
        {
            // Registering the key handling events 
            m_MainForm.KeyUp += new System.Windows.Forms.KeyEventHandler(Manager.UIManager_KeyUp);
            m_MainForm.KeyDown += new System.Windows.Forms.KeyEventHandler(Manager.UIManager_KeyDown);
            m_MainForm.KeyPress += new System.Windows.Forms.KeyPressEventHandler(Manager.UIManager_KeyPress);
        }

        /// <summary>
        /// Threshold value to skip show if the UI was hidden to soon. 
        /// </summary>
        private const long SHOWHIDE_UI_THRESHOLD = 1800000;
 
        /// <summary>
        /// Shows or Hides the UI depending on its visibility. 
        /// </summary>
        void IUIProvider.ShowHideAction(ShowHideReason reason)
        {
            System.Diagnostics.Debug.WriteLine("ShowHideUI (StandardUIProvider.cs)", "UI");

            if (m_MainForm.Visible)
            {
                m_MainForm.HideUI();

                // Disabling text entry mode 
                if (m_TextEntryActive)
                {
                    TextEntryMode(false);
                }
            }
            else
            {
                // If the reason is clicking on notify icon then we are going to check the difference 
                // between the last hide and the current time, if the difference is smaller then the
                // threshold value, we are not going to show the UI since it was just only hidden. 
                // 
                // This is needed because if the notify icon is clicked while the UI is visible then 
                // the form gets deactivated first and then the click processed only flashing the UI 
                // instead of hiding it. 
                if (reason == ShowHideReason.NotifyIcon)
                {
                    long diff = DateTime.Now.Ticks - m_MainForm.GetLastDeactivatedInTicks(); 
                    System.Diagnostics.Debug.WriteLine("NotifyIcon within HideShow " + (diff) , "UI");

                    if (diff < SHOWHIDE_UI_THRESHOLD)
                    {
                        return;
                    }
                }

                m_MainForm.ShowUI();
            }
        }

        /// <summary>
        /// Tells if the ui visible or not.
        /// </summary>
        /// <returns>Returns true if the ui visible, false otherwise</returns>
        bool IUIProvider.IsUIVisible()
        {
            return m_MainForm.Visible; 
        }

        /// <summary>
        /// Escapes the UI
        /// </summary>
        /// <remarks>
        /// Hides the list if it is visible, hides the complete UI if the list is not show 
        /// </remarks>
        void IUIProvider.EscapeAction()
        {
            System.Diagnostics.Debug.WriteLine("EscapeAction (StandardUIProvider.cs)", "UI");
            if (m_MainForm.Visible)
            {
                if (m_MainForm.IsItemListVisible())
                {
                    m_MainForm.HideItemList();
                }
                else
                {
                    m_MainForm.Hide();

                    // Disabling text entry mode
                    if (m_TextEntryActive)
                    {
                        TextEntryMode(false);
                    }
                }
            }
        }

        /// <summary>
        /// Returns the list of UI slots 
        /// </summary>
        /// <returns>list of UI slots</returns>
        List<IUIDisplaySlot> IUIProvider.GetListOfUISlots()
        {
            return m_MainForm.GetDisplaySlots();
        }

        /// <summary>
        /// Activates a given ui slot. 
        /// </summary>
        /// <param name="slotIndex">index of the slot to b e activated</param>
        void IUIProvider.ActivateUISlot(int slotIndex)
        {
            System.Diagnostics.Debug.Assert(slotIndex >= 0, "ActivateUISlot has a smaller than 0 slot index!");
            System.Diagnostics.Debug.Assert(m_MainForm.GetDisplaySlots() != null, "ActivateUISLot has a null slot list!");
            m_MainForm.ActivateUISlot(slotIndex);

            // Need to erase the searchkey after activating a new slot with tab     
            ((IUIProvider)this).CurrentDisplaySlot.EraseSearchKey(); 
        }
        /// <summary>
        /// Index of the selected UI slot 
        /// </summary>
        int SelectedUISlotIndex
        {
            get
            {
                return m_MainForm.GetCurrentDisplaySlotIndex();
            }
            set
            {

            }
        }

        /// <summary>
        /// Selects the next UI slot visible. 
        /// </summary>
        void SelectNextUISlot()
        {
            m_MainForm.SelectNextUISlot();

            // Need to erase the searchkey after activating a new slot with tab             
            ((IUIProvider)this).CurrentDisplaySlot.EraseSearchKey();
        }

        IUIDisplaySlot IUIProvider.CurrentDisplaySlot
        {
            get
            {
                int sel = m_MainForm.GetCurrentDisplaySlotIndex();
                return m_MainForm.GetDisplaySlots()[sel];
            }
        }

        /// <summary>
        /// Implements Tab Action
        /// </summary>
        /// <remarks>
        /// Needs to activate the new selected slot 
        /// </remarks>
        void IUIProvider.TabAction()
        {
            if (IsTextEntryActive)
            {
                TextEntryMode(false);
            }

            SelectNextUISlot();
        }

        /// <summary>
        /// Text mode action 
        /// </summary>
        /// <remarks>
        /// Changes the UI to text entry mode. 
        /// </remarks>
        public void TextEntryMode(bool enabled)
        {
            SubjectItemController subject = m_MainForm.SubjectSlot; 

            if (!subject.SelectedSlot)
            {
                m_MainForm.ActivateUISlot(frmMain.SUBJECTSLOT_INDEX);
            }

            if (enabled)
            {
                subject.EnableTextEntryMode();
            }
            else
            {                
                subject.DisableTextEntryMode();
            }

            m_TextEntryActive = enabled; 
        }

        public bool IsTextEntryActive
        {
            get
            {
                return m_TextEntryActive; 
            }
        }

        #endregion
    }
}
